#include "YM2612Value.h"	
#include "YM2612StateData.h"

//-------------------------------------------------------------------------------------------------------
//YM2612Value - Pairs a parameter with a value and 
//              ensures it stays within range
//-------------------------------------------------------------------------------------------------------
YM2612Value::YM2612Value()
{
	InitializeDefaults();
}

//-------------------------------------------------------------------------

YM2612Value::YM2612Value( YM2612Param param, unsigned char min, unsigned char max, unsigned char value )
{
	InitializeDefaults();
	Init( param, min, max, value );
}

//-------------------------------------------------------------------------

void YM2612Value::InitializeDefaults()
{
	_index = 0;
	_midi = 0;
	_midiLearn = false;
	_owner = nullptr;
    _channel = 0;
	_op = 0;
	_min = 0;
	_max = 0;
	_value = 0;
}

//-------------------------------------------------------------------------

void YM2612Value::MidiModified()
{
	if( _owner != nullptr )
		_owner->MidiControls[this] = true;
}

//-------------------------------------------------------------------------

void YM2612Value::Init( YM2612Param param, unsigned char min, unsigned char max, unsigned char value )
{
	_param = param;
	_min = min;
	_max = max;
	_value = value;
}

//-------------------------------------------------------------------------

void YM2612Value::SetValue( int value )
{
	_value = value;
	if( _value < _min )
		_value = _min;
	else if( _value > _max )
		_value = _max;
}

//-------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------------
//YM2612Values - A collection of YM2612Value structures
//-------------------------------------------------------------------------------------------------------
YM2612Values::YM2612Values()
	:Op(0)
	,Channel(0)
{

}

//-------------------------------------------------------------------------

YM2612Value& YM2612Values::GetParam( YM2612Param param )
{
	for( int i = 0; i < NumParams(); i++ )
	{
		YM2612Value* val = CastValueData(i);
		if( val->GetParam() == param )
			return *val;
	}
	return *CastValueData(0);
}

//-------------------------------------------------------------------------

YM2612Value* YM2612Values::GetParamByIndex( int index )
{
	for( int i = 0; i < NumParams(); i++ )
	{
		YM2612Value* val = CastValueData(i);
		if( val->GetIndex() == index )
			return val;
	}
	return nullptr;
}

//-------------------------------------------------------------------------
	
YM2612Value* YM2612Values::operator[]( int index )
{
	if( index < 0 || index > NumParams() )
		return nullptr;

	return CastValueData(index);
}

//-------------------------------------------------------------------------

//Casts an index to a pointer in the class data to a YM2612Value
YM2612Value* YM2612Values::CastValueData( int index )
{
	return (YM2612Value*)(((char*)this) + (sizeof(int) * 3) + (index * sizeof(YM2612Value)));
}

//-------------------------------------------------------------------------

void YM2612Values::SetChannel( int channel )
{
	for( int i = 0; i < NumParams(); i++ )
	{
		YM2612Value* val = CastValueData(i);
		val->SetChannel( channel );
	}
	Channel = channel;
}

//-------------------------------------------------------------------------

void YM2612Values::SetOp( int op )
{
	for( int i = 0; i < NumParams(); i++ )
	{
		YM2612Value* val = CastValueData(i);
		val->SetOp( op );
	}
	Op = op;
}

//-------------------------------------------------------------------------